package com.hospital.workstation.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.XmlUtil;
import com.hospital.workstation.webService.domain.Request;
import com.hospital.workstation.webService.domain.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.scheduling.support.SimpleTriggerContext;

import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName CXFClientUtil
 * @description: webservice调用服务端接口
 * @author: whb
 * @create: 2023-04-11 11:25
 * @Version 1.0
 **/
@Slf4j
public class CXFClientUtil {
    // wsdl地址
    //private final static String wsdlUrl = "http://192.168.3.220:8080/services/ws/api?wsdl";
    private final static String wsdlUrl = "http://10.10.11.4/csp/hsb/DHC.Published.PUB0029.BS.PUB0029.CLS?WSDL";

    /**
     * CXF动态调用webservice服务端
     *
     * @param methodName 方法名
     * @param params     参数
     * @return
     */
    public static String sendXml(String methodName, Map<String, Object> params) {
        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(wsdlUrl);
        // 需要密码的情况需要加上用户名和密码
        // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
        // 下面一段处理 WebService接口和实现类namespace不同的情况
        // CXF动态客户端在处理此问题时，会报No operation was found with the name的异常
        Endpoint endpoint = client.getEndpoint();
        QName opName = new QName(endpoint.getService().getName().getNamespaceURI(), methodName);
        BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding();
        if (bindingInfo.getOperation(opName) == null) {
            for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) {
                if (methodName.equals(operationInfo.getName().getLocalPart())) {
                    opName = operationInfo.getName();
                    break;
                }
            }
        }
        Object[] objects = new Object[0];
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            objects = client.invoke(opName, params.get("code"), params.get("xml"));
            log.debug("返回数据:" + objects[0]);
            return objects[0].toString();
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return null;
    }

    /**
     * 类型转换
     * @param data xml
     * @return
     */
    public static Request<T> getRequest(String data) {
        Map map = XmlUtil.xmlToMap(data);
        Request request = BeanUtil.toBean(map, Request.class);
        return request;
    }

    public static void main(String[] args) {
        // 远程webService的URL
        //String hostUrl = "http://192.168.3.220:8080/services/ws/api?wsdl";
        // 方法名
        String methodName = "SendMessageInfo";
        // 请求参数
        // Object[] parameters = new Object[]{"MES0073", "123789"};
        //String param = "MES0073";
        // 调用服务端接口
        //Object b = invokeRemoteMethodByCache(hostUrl, methodName, param);

        Map<String, Object> params = new HashMap<>();
        params.put("code", "MES0073");
        params.put("xml", new Response().getMES0073Xml());
        String sendMessageInfo = sendXml("SendMessageInfo", params);
        Console.log(sendMessageInfo);
    }
}
